home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 49
/
Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso
/
-serious-
/
misc
/
charmap
/
source
/
cmap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-30
|
14KB
|
433 lines
/******************************************************************
** charmap.c : Affiche la table ascii d'une police de caractère **
** Écrit (en partie) par T.Pierron **
** 14-11-1999 **
**---------------------------------------------------------------**
** Special Requirements: WorkBench 2.0, version 36 or above **
******************************************************************/
#include <Intuition/Intuition.H>
#include <Intuition/IntuitionBase.H>
#include <Graphics/RastPort.H>
#include <Graphics/Text.H>
#include <Libraries/Gadtools.H>
#include <Intuition/Screens.H>
#include "cmap.h"
#define CATCOMP_NUMBERS /* We will need the string id */
#define CATCOMP_STRINGS /* and the english string corresponding to this id */
#include "cmap_strings.h"
/* Shared libraries we'll need to open */
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct Library *GadToolsBase = NULL;
struct Library *AslBase = NULL;
struct Library *DiskfontBase = NULL;
struct Library *CxBase = NULL;
struct Library *IconBase = NULL;
struct Library *KeymapBase = NULL;
struct Library *LocaleBase = NULL;
void *clipdev = NULL;
/* Graphics area: */
struct RastPort *RP,RPT;
struct TextFont *font,*newfont=0;
struct Menu *menu = NULL; /* Menu attached to the window */
struct Screen *screen = NULL; /* Screen where window will be opened */
struct Window *window = NULL; /* Main window ptr */
struct Gadget *glist = NULL; /* Gadget list pointer */
struct Gadget *gad; /* our running Gadget pointer */
void *vi = NULL; /* VisualInfo pointer */
WORD ZoomData[4]; /* Position of iconified window */
WORD xdeb,ydeb,xfin,yfin,X,Y; /* Position of ASCII table */
UBYTE CharWid[256],Char[]=" "; /* Data of ASCII table */
UBYTE Font_height; /* Font information */
UBYTE GadDisable=0; /* If ressource unavailable */
/* For the "version" command: */
const UBYTE VERSION[]= "$VER:CharMap v" CHARMAP_VERSION " 14/11/1999\n";
/* Tag list for openning the main window: */
ULONG WinTags[] = {
WA_Zoom,(ULONG)ZoomData,
WA_NewLookMenus,TRUE,
TAG_DONE
};
/* For our string gadget: */
ULONG StrTags[] = {
GTST_MaxChars,50,
TAG_DONE
};
/* Set the color of the menu to Newlook (only 3.0+): */
ULONG MenuTags[] = {
GTMN_FrontPen, 1,
TAG_DONE
};
ULONG BoxTags[] = {
GT_VisualInfo,0,
TAG_DONE,FALSE,
TAG_DONE
};
/* Our gadtools gadgets text: */
UBYTE *GadTxt[]={
MSG_STRGAD_STR,
MSG_COPY_STR,
MSG_PASTE_STR,
MSG_CLEAR_STR,
MSG_NEWFONT_STR
};
/* here we declare the information for our new window - notice that GadTools
* provides some constants which describe which IDCMP events the Window will
* need to handle the GadTools Gadgets properly. Just OR them into your
* normal IDCMPFlags field.
*/
ULONG sigwin=0;
struct NewWindow new_window = {
50, 20, 510, 150,
-1, -1, /* DetailPen, BlockPen */
CLOSEWINDOW | REFRESHWINDOW | MOUSEBUTTONS | MOUSEMOVE | RAWKEY | MENUPICK | MENUVERIFY | GADGETUP,
ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | REPORTMOUSE,
NULL, /* FirstGadget */
NULL, /* CheckMark */
MSG_WINTITLE_STR,
NULL, /* Screen */
NULL, /* BitMap */
0, 0, 0, 0, /* min/max sizes */
CUSTOMSCREEN
};
/* Error messages: */
UBYTE *Errors[]= {
MSG_BADOS_STR,
MSG_SCREENLOCK_STR,
MSG_ERRMENUBAR_STR,
MSG_ERRLAYOUT_STR,
MSG_FONTTOOBIG_STR,
MSG_ERRGADGET_STR
};
#define ErrMsg(num) Errors[ num-MSG_BADOS ]
struct EasyStruct Request=
{ sizeof(struct EasyStruct),0,
MSG_ABOUT_STR,
MSG_ABOUTMSG_STR,
MSG_CONTINUE_STR
};
/**********************************************************
***** MENU DATA MANAGMENT: *****
**********************************************************/
/* NewMenu menu declaration */
struct NewMenu newmenu[] =
{
{NM_TITLE, MSG_MENUTITLE_STR,0 , 0, 0, 0},
{ NM_ITEM, MSG_MENUFONTSCREEN_STR,"S", CHECKIT|CHECKED, ~1, (APTR) 11},
{ NM_ITEM, MSG_MENUTEXTFONT_STR, "T", CHECKIT, ~2, (APTR)12},
{ NM_ITEM, MSG_MENUCUSTOMFONT_STR,"F", CHECKIT, ~4, (APTR)13},
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
{ NM_ITEM, MSG_MENUCHARSET_STR, 0, 0, 0, 0},
{ NM_SUB, MSG_MENUASCII8_STR, "1", CHECKIT, ~1, (APTR)141},
{ NM_SUB, MSG_MENUISOLATIN1_STR, "2", CHECKIT|CHECKED, ~2, (APTR)142},
{ NM_SUB, MSG_MENUSTDAMIGA_STR, "3", CHECKIT, ~4, (APTR)143},
{ NM_ITEM, MSG_MENUCLEARTXT_STR, "Del", NM_COMMANDSTRING, 0, (APTR)14},
{ NM_ITEM, MSG_NEXTSCR_STR, "J", 0, 0, (APTR)15},
{ NM_ITEM, MSG_MENUABOUT_STR, "?", 0, 0, (APTR)16},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0},
{ NM_ITEM, MSG_MENUICONOFY_STR, "I", 0, 0, (APTR)17},
{ NM_ITEM, MSG_MENUHIDE_STR, "H", 0, 0, (APTR)18},
{ NM_ITEM, MSG_MENUQUIT_STR, "Q", 0, 0, (APTR)19},
{NM_END, 0, 0, 0, 0, 0},
},*checked=&newmenu[1],
*checkset=&newmenu[7];
/* Different width of box for each charset: */
UBYTE MaxWid,NumChars;
UBYTE CharsetNum=2;
/* Colors pens: */
UWORD fillpen=3,txtpen=1,poppen=2,filltxt=2;
/* Function prototypes */
BYTE setup(); /* Open window, ressources, font... */
void cleanup(UBYTE *,WORD); /* Quit properly */
void create_gadgets(void); /* Create the gadget using gadtools lib */
void handle_input(void); /* Handle intuition events */
void Init_helpwin(); /* Alloc memory for help window */
void Open_helpwin(UBYTE, WORD, WORD); /* Show the help window */
void Free_helpwin(); /* Free all allocated memory */
void Close_helpwin(); /* Cleanup the display */
/**** Definition of the main loop: ****/
int main(int argc, char *argv[])
{
extern BOOL PopWin; /* True if the window is poped up at start */
/* Open ze libraries */
if( (CxBase = (void *) OpenLibrary("commodities.library", 37L)) &&
(IconBase = (void *) OpenLibrary("icon.library", 36L)) )
/* If the icon and commodities.library are present, and the **
** programm failed to init as a commodity, it's probably **
** because it is already running, and user want to quit: */
{ if( Init_commodity(argc,argv)==FALSE )
cleanup(0,0);
} else
newmenu[14].nm_Flags |= NM_ITEMDISABLED; /* If no commo., can't hide the interface */
/* These libraries are located in ROM. If it failed to open, it's **
** because we are attempting to run this porgramm on an old system */
if( !(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", MIN_VERSION)) ||
!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",MIN_VERSION)) ||
!(GadToolsBase = (struct Library *)OpenLibrary("gadtools.library",MIN_VERSION)) ||
!(KeymapBase = (struct Library *)OpenLibrary("keymap.library",37)) )
cleanup(ErrMsg(MSG_BADOS),30);
/* If no locale, use english as default: */
if(LocaleBase = (struct Library *)OpenLibrary("locale.library", 38))
Translate_srings();
/* No ASL or diskfont libraries, no ASL font requester */
if( !(AslBase = (struct Library *)OpenLibrary("asl.library",MIN_VERSION)) ||
!(DiskfontBase = (struct Library *)OpenLibrary("diskfont.library",0)) ) {
newmenu[3].nm_Flags |= NM_ITEMDISABLED;
GadDisable |= 8;
}
/* For temporary font measurement: */
InitRastPort( &RPT );
/* get access to the WorkBench screen */
screen = (struct Screen *) IntuitionBase->ActiveScreen;
font = screen->RastPort.Font;
Init_charset(font);
if(PopWin)
/* If setup failed at start (font too big): */
if(setup()) Handle_menu(13L);
handle_input();
}
/**** Setup the window, return 1 if init failed: ****/
BYTE setup()
{
struct DrawInfo *di;
/* get the screen's visual information data */
if( !(vi = (void *) GetVisualInfoA( screen,NULL )) )
cleanup(ErrMsg(MSG_SCREENLOCK),30);
BoxTags[1]=(ULONG)vi;
/* Adjust the pen number to what the screen uses: */
if( di = (void *)GetScreenDrawInfo(screen))
{
/* Get a copy of the correct pens for the screen: */
fillpen = di->dri_Pens[FILLPEN];
txtpen = di->dri_Pens[TEXTPEN];
filltxt = poppen = di->dri_Pens[FILLTEXTPEN];
if(poppen==txtpen) poppen=fillpen;
/* This one is only available on system V39+: */
if(di->dri_Version>=2) MenuTags[1] = di->dri_Pens[BARDETAILPEN];
FreeScreenDrawInfo(screen,di);
}
/* Build the menu-strip */
if( !(menu = (void *) CreateMenusA(newmenu, MenuTags)) )
cleanup(ErrMsg(MSG_ERRMENUBAR),30);
/* Compute the size of the menus: */
if( !LayoutMenusA(menu, vi, NULL))
cleanup(ErrMsg(MSG_ERRLAYOUT),30);
SetFont(&RPT,font);
/* Read the size of the 256 characters of the current font, **
** and compute the maximal width of the box chars: */
NumChars = CharsetNum==1 ? 32 : CharsetNum == 2 ? 28 : 24;
{
register WORD I;
register UBYTE *W;
for(I=0,W=CharWid,MaxWid=0; I<256; I++,W++) {
*Char = I;
*W = TextLength(&RPT,Char,1);
/* Compute the width of each box: */
switch( CharsetNum )
{
case 3: if(I>=128 && I<160) break;
case 2: if(I<32) break;
case 1: if(MaxWid < *W+6) MaxWid=*W+6;
}
}
}
Font_height = font->tf_YSize+4;
/* Compute the exact size of our window: */
new_window.Width = xfin = MaxWid*NumChars+20;
new_window.Height = Font_height*8+3*screen->Font->ta_YSize+35;
new_window.Screen = screen;
new_window.LeftEdge = 50;
if(xfin+50 > screen->Width)
new_window.LeftEdge = screen->Width-xfin>>1;
/* Init the position and the size of the iconified window: */
ZoomData[0] = 50;
ZoomData[1] = 50;
ZoomData[2] = TextLength(&screen->RastPort,new_window.Title,strlen(new_window.Title))+100;
ZoomData[3] = screen->BarHeight+1;
/* Does the window fit in the screen? */
if( !(window = (void *) OpenWindowTagList(&new_window,WinTags)) )
/* If ASL is avaible, show a requester to change the font: */
if( avert(ErrMsg(MSG_FONTTOOBIG)) && AslBase )
return TRUE;
else cleanup(0,0);
/* Signal bit, to process events from the window: */
sigwin = 1 << window->UserPort->mp_SigBit;
SetMenuStrip(window, menu); /* Attach the menu to the window */
create_gadgets(); /* Creates all gadgets */
Init_helpwin(); /* Init the help win, using width height of the current font: */
return FALSE;
}
/**** Desallocate all ressources: ****/
void cleanup(UBYTE *msg,WORD err)
{
extern APTR FR;
extern void *catalog;
if (msg) puts(msg);
if (window) {
ClearMenuStrip(window);
CloseWindow(window);
window=NULL;
}
/* These two functions can take a NULL, but let's stay consistent */
if (glist) FreeGadgets(glist); glist=0;
if (vi) FreeVisualInfo(vi); vi=0;
if (menu) FreeMenus(menu); menu=0;
Free_helpwin();
if (err<0) return;
Free_commodity();
if (FR) FreeAslRequest(FR);
if (newfont) CloseFont(newfont);
if (catalog) CloseCatalog(catalog);
if (clipdev) CBClose(clipdev);
if (CxBase) CloseLibrary(CxBase);
if (AslBase) CloseLibrary(AslBase);
if (IconBase) CloseLibrary(IconBase);
if (KeymapBase) CloseLibrary(KeymapBase);
if (LocaleBase) CloseLibrary(LocaleBase);
if (DiskfontBase) CloseLibrary(DiskfontBase);
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (GfxBase) CloseLibrary(GfxBase);
exit(err);
}
/**** Draw the table of characters: ****/
void Draw_ASCIIChart()
{
register WORD i,x,y;
/* Initial bevel box, which will be copied 256 times: */
DrawBevelBoxA(RP,xdeb,ydeb,MaxWid,Font_height,BoxTags);
/* Exponential copy (very fast :-) */
for(x=MaxWid,i=xdeb+x,y=window->Width-10; i<xfin; ) {
ClipBlit(RP,xdeb,ydeb,RP,i,ydeb,x,Font_height,0xC0);
i+=x; x<<=1; if(i+x>y) x=y-i;
}
for(x=Font_height,i=ydeb+x; i<yfin; i+=x,x<<=1)
ClipBlit(RP,xdeb,ydeb,RP,xdeb,i,y,x,0xC0);
/* Character in each box: */
SetAPen(RP,txtpen);
for(i=CharsetNum==1?0:32,x=xdeb; i<256; i++,y+=Font_height)
{
if( (i&7)==0 ) { y=ydeb; x+=MaxWid; }
if( CharsetNum==3 && i==128) i=160;
*Char = i;
Move(RP,x-(MaxWid+CharWid[i]>>1),y+font->tf_Baseline+2);
Text(RP,Char,1);
}
}
/**** Create the gadgets of the window: ****/
void create_gadgets()
{
# define tmpgad ((struct Gadget *)RP)
struct NewGadget ng={65,5,0,14,0,0,0,PLACETEXT_LEFT | NG_HIGHLABEL,0,0};
extern UBYTE *StrBuf;
UWORD top,I,W;
top = window->BorderTop + 1;
gad = (void *) CreateContext(&glist);
RP = &screen->RastPort;
/* the NewGadget stucture is not modified by any Gadget creation call,
so you'll only need to change information that actually needs to be
changed */
ng.ng_GadgetText = GadTxt[0];
ng.ng_TextAttr = screen->Font;
ng.ng_Width = window->Width - 10 -
(ng.ng_LeftEdge = TextLength(RP,GadTxt[0],strlen(GadTxt[0]))+20);
ng.ng_Height = screen->Font->ta_YSize+6;
ng.ng_VisualInfo = vi;
ng.ng_TopEdge += top;
tmpgad = gad = (void *) CreateGadgetA(STRING_KIND, gad, &ng, StrTags);
/* Show the name of the font in the string gadget: */
StrBuf = sti(gad)->Buffer;
strcpy(StrBuf,font->tf_Message.mn_Node.ln_Name);
/* Create the 4 gadgets shorcut: */
ng.ng_Width = W = (ng.ng_Width - 30) / 4;
ng.ng_Height -= 2;
ng.ng_Flags = PLACETEXT_IN;
top = (ng.ng_TopEdge += ng.ng_Height+5);
for(I=0,W+=10; I<4; ng.ng_LeftEdge+=W)
{
ng.ng_GadgetID = ++I;
ng.ng_GadgetText = GadTxt[I];
tmpgad = (void *) CreateGadgetA(BUTTON_KIND, tmpgad, &ng, NULL);
/* If a ressource isn't available, disable the corresponding gadget: */
if(GadDisable & (1<<I-1)) tmpgad->Flags |= GADGDISABLED;
}
/* Now we're ready to add the Gadget list. Quit if the final Gadget
pointer is NULL - this means that one of the Gadget allocations failed.
If it exists, add it to the window and refresh, then add the new
GT_RefreshWindow() call. */
if (!tmpgad)
cleanup(ErrMsg(MSG_ERRGADGET),30);
AddGList(window, glist, (UWORD)-1, (UWORD)-1, NULL);
RefreshGList(glist, window, NULL, (UWORD)-1);
GT_RefreshWindow(window, NULL);
RP=window->RPort;
SetFont(RP,font);
SetDrMd(RP,JAM1);
/* Create the ASCII table: */
xdeb = 10; ydeb = top+ng.ng_Height+5;
xfin -= 10; yfin = ydeb+Font_height*8;
Draw_ASCIIChart();
}